package Gestor;

import Clases.Empleado;
import Clases.HoraExtra;
import Clases.Pago;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.LogicalExpression;
import org.hibernate.criterion.Restrictions;

public class GestorEmpleado extends GestorBase {

    private static GestorEmpleado instancia = null;
    private static final String FN_VERIFICAR_INSERTAR = "select FN_INSERTAR_EMPLEADO(:cedula,:codigo)";
    private static final String SP_CREAR_PAGOS="SP_CREAR_PAGOS";
    public static GestorEmpleado obtenerInstancia() {
        if (instancia == null) {
            instancia = new GestorEmpleado();
        }
        return instancia;
    }

    private GestorEmpleado() {
    }

    @Override
    public Object insertar(Object objeto) {
        Object guardo = null;
        try {
            iniciaOperacion();
            guardo = sesion.save(objeto);
            tx.commit();

        } catch (HibernateException he) {
            manejaExcepcion(he);
        } finally {
            sesion.close();
        }

        return guardo;
    }

    @Override
    public boolean InsertarOActualizar(Object nuevoObjeto) {
        boolean verifica = false;
        try {
            Empleado empleadoTemp = this.getEmpleadoCedula(((Empleado) nuevoObjeto).getCedula());
            if (empleadoTemp != null) {
                ((Empleado) nuevoObjeto).setNumEmpleado(empleadoTemp.getNumEmpleado());
            }
            iniciaOperacion();
            sesion.saveOrUpdate(nuevoObjeto);
            tx.commit();
            verifica = true;
        } catch (HibernateException he) {
            verifica = false;
            System.out.println(he.getCause());
            System.out.println(he.getMessage());
            manejaExcepcion(he);

        } finally {
            sesion.close();
        }
        return verifica;
    }

   /* @Override
    public boolean eliminar(Object empleado) throws HibernateException {
        int verificacionEmpleado = 0;
        boolean exito = false;
        try {
            iniciaOperacion();
            verificacionEmpleado = sesion.createSQLQuery("DELETE FROM empleado WHERE numEmpleado=:num")
                    .setParameter("num", ((Empleado) empleado).getNumEmpleado())
                    .executeUpdate();

            if (verificacionEmpleado >= 1) {
                exito = true;
                tx.commit();
            }
        } catch (HibernateException he) {
            manejaExcepcion(he);
            verificacionEmpleado = 0; //error
            throw he;
        } finally {
            sesion.close();
        }

        return exito;
    }*/

    public Empleado getEmpleado(long codigo) throws HibernateException {
        Empleado empleado = null;
        try {
            iniciaOperacion();

            Object e = sesion.get(Empleado.class, codigo);
            if (e != null) {
                empleado = (Empleado) e;
            }

        } catch (HibernateException he) {
            manejaExcepcion(he);
            throw he;
        } finally {
            sesion.close();
        }

        return empleado;
    }

    public Empleado getEmpleadoCedula(long cedula) throws HibernateException {
        Empleado empleado = null;
        try {
            iniciaOperacion();
            Object e = sesion.createQuery("from Empleado where cedula= :? and fechaFin is null")
                    .setParameter("?", cedula).uniqueResult();
            if (e != null) {
                empleado = (Empleado) e;
            }
        } catch (HibernateException he) {
            manejaExcepcion(he);
            throw he;
        } finally {
            sesion.close();
        }

        return empleado;
    }

    public Empleado getEmpleadoCedulaHistorico(long cedula) throws HibernateException {
        Empleado empleado = null;
        try {
            iniciaOperacion();
            Object e = sesion.createQuery("from Empleado where cedula= :? and fechaFin is not null")
                    .setParameter("?", cedula).uniqueResult();
            if (e != null) {
                empleado = (Empleado) e;
            }
        } catch (HibernateException he) {
            manejaExcepcion(he);
            throw he;
        } finally {
            sesion.close();
        }

        return empleado;
    }

    public Empleado getEmpleadoCodigo(long codigo) throws HibernateException {
        Empleado empleado = null;
        try {
            iniciaOperacion();
            Object e = sesion.createQuery("from Empleado where codigo= :? and fechaFin is null")
                    .setParameter("?", codigo).uniqueResult();
            if (e != null) {
                empleado = (Empleado) e;
            }
        } catch (HibernateException he) {
            manejaExcepcion(he);
            throw he;
        } finally {
            sesion.close();
        }

        return empleado;
    }

    public Empleado getEmpleadoNum(long numEmpleado) throws HibernateException {
        Empleado empleado = null;
        try {
            iniciaOperacion();
            Object e = sesion.createQuery("from Empleado where numEmpleado=:? and fechaFin is null").setParameter("?", numEmpleado).uniqueResult();
            if (e != null) {
                empleado = (Empleado) e;
            }
        } catch (HibernateException he) {
            manejaExcepcion(he);
            throw he;
        } finally {
            sesion.close();
        }

        return empleado;
    }

    public List<Empleado> getEmpleadosNombre(String nombre) throws HibernateException {
        List listaEmpleados = null;
        try {
            iniciaOperacion();
            listaEmpleados = sesion.createQuery("from Empleado where nombre like %:?% and fechaFin is null").setParameter("?", nombre).list();
        } catch (HibernateException he) {
            manejaExcepcion(he);
            throw he;
        } finally {
            sesion.close();
        }

        return listaEmpleados;
    }

    public List<Empleado> getEmpleadosApellido1(String nombre) throws HibernateException {
        List listaEmpleados = null;
        try {
            iniciaOperacion();
            listaEmpleados = sesion.createQuery("from Empleado where apellido1 like %:?% and fechaFin is null").setParameter("?", nombre).list();
        } catch (HibernateException he) {
            manejaExcepcion(he);
            throw he;
        } finally {
            sesion.close();
        }

        return listaEmpleados;
    }

    public ArrayList<Empleado> obtenerListaEmpleados() throws HibernateException {
        ArrayList<Empleado> listaEmpleados = null;

        try {
            iniciaOperacion();
            listaEmpleados = (ArrayList<Empleado>) sesion.createQuery("from Empleado order by codigo").list();
        } finally {
            sesion.close();
        }

        return listaEmpleados;
    }
    
    public ArrayList<Empleado> obtenerListaEmpleadosBancarios(){
    ArrayList<Empleado> listaEmpleados=null;
    String tipoPago="Cuenta Bancaria";
    iniciaOperacion();
    listaEmpleados=(ArrayList<Empleado>) sesion.createQuery("from Empleado where opcionPago=:?  order by codigo").setParameter("?", tipoPago).list();
    return listaEmpleados;
          
            
    }

    public ArrayList<Empleado> obtenerListaEmpleadosActuales() throws HibernateException {
        ArrayList<Empleado> listaEmpleados = null;

        try {
            iniciaOperacion();
            listaEmpleados = (ArrayList<Empleado>) sesion.createQuery("from Empleado where fechaFin is null order by codigo").list();
        } finally {
            sesion.close();
        }

        return listaEmpleados;
    }

    public ArrayList<Empleado> obtenerListaEmpleadosHistoricos() throws HibernateException {
        ArrayList<Empleado> listaEmpleados = null;

        try {
            iniciaOperacion();
            listaEmpleados = (ArrayList<Empleado>) sesion.createQuery("from Empleado where fechaFin is not null order by codigo").list();
        } finally {
            sesion.close();
        }

        return listaEmpleados;
    }

    public int getHorasExtraEmpleado(long numEmpleado, Date fecha) {
        int cant = 0;

        try {
            iniciaOperacion();
            Criteria cr = sesion.createCriteria(HoraExtra.class);
            Criterion numeroEmpleado = Restrictions.eq("id.numEmpleado", numEmpleado);
            Criterion fecha1 = Restrictions.eq("id.fecha", fecha);
            LogicalExpression andExp = Restrictions.and(numeroEmpleado, fecha1);
            cr.add(andExp);
            HoraExtra hora = (HoraExtra) cr.uniqueResult();
            if(hora != null){
                cant = hora.getHoras();
            }else{
                cant=0;
            }
        } finally {
            sesion.close();
        }

        return cant;
    }
    
    public boolean hayPagos(Date fechaPagoInicio) {
        boolean hayPagos = false;

        try {
            iniciaOperacion();
            int count1 = ((Long)sesion.createQuery("select count(*) from Empleado where fechaFin is null").iterate().next() ).intValue();
            int count2 = ((Long)sesion.createQuery("select count(*) from Pago where fechaPagoInicio=:inicio").setParameter("inicio", fechaPagoInicio)
                    .iterate().next() ).intValue();
            if(count1==count2){
                hayPagos=true;
            }
                
        }catch(HibernateException  e){
            hayPagos=false;
            System.out.println(e.getCause());
            System.out.println(e.getMessage());
        }finally {
            sesion.close();
        }

        return hayPagos;
    }

     public void crearPagos() {

        ArrayList<Pago> pagos = new ArrayList<>();
        try {
            
            ResultSet rs = llamarProcedimientoAlmacenado(SP_CREAR_PAGOS, null);
            
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException| HibernateException | SQLException e ) {
            System.out.println(e.getMessage());
        } finally {
        }
    }
}
